package chen.videoedit;


import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.media.MediaMuxer;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.widget.Toast;

import java.io.IOException;
import java.nio.ByteBuffer;


/**
 * 视频音轨视轨 分流 保存
 * 问题MediaFormat.MIMETYPE_AUDIO_MPEG 编码器无法初始化
 */
public class SplitActivity extends BasisActivity {


    private MediaExtractor mediaExtractor;
    private int videoTrack;
    private MediaFormat VideomediaFormat;
    private int audioTrack;
    private MediaFormat AudiomediaFormat;

    @Override
    public int setlayoutResID() {
        return R.layout.activity_split;
    }

    @Override
    public void initialView(Bundle arg0) {
        findViewById(R.id.split_bt).setOnClickListener(this);
    }

    @Override
    public void setActivity() {
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.split_bt:
                Toast.makeText(this, "点击了", Toast.LENGTH_SHORT).show();
                MyThread thread = new MyThread();
                thread.start();
                break;
        }
    }

    class MyThread extends Thread {
        @Override
        public void run() {
            split(Environment.getExternalStorageDirectory() + "/test.MP4", Environment.getExternalStorageDirectory() + "/testVideo.mp4", Environment.getExternalStorageDirectory() + "/testVideo.mp3");
        }
    }

    /**
     * 视频音轨视轨 分流 保存
     *
     * @param path            视频路径
     * @param save_video_path
     */
    public void split(String path, String save_video_path, String save_aideo_path) {

        mediaExtractor = new MediaExtractor();//初始化提取器
        try {
            mediaExtractor.setDataSource(path);
        } catch (IOException e) {
            Log.e("error", "路径 path 错误" + e.getMessage());
        }
        int count = mediaExtractor.getTrackCount();
        //获取每个轨道的信息
        for (int i = 0; i < count; i++) {
            MediaFormat mediaFormat;
            if (mediaExtractor != null) {
                mediaFormat = mediaExtractor.getTrackFormat(i);
                String mime = mediaFormat.getString(MediaFormat.KEY_MIME);
                if (mime.startsWith("video/")) {
                    videoTrack = i;
                    VideomediaFormat = mediaFormat;
                    Log.e("jjj",VideomediaFormat.toString());
                }
                if (mime.startsWith("audio/")) {
                    audioTrack = i;
                    AudiomediaFormat = mediaFormat;
                    Log.e("jjj",AudiomediaFormat.toString());
                }
            }
        }
        splitVideo(videoTrack, VideomediaFormat, save_video_path);//视频
        splitAudio(audioTrack, AudiomediaFormat, save_aideo_path);
        mediaExtractor.release();
        mediaExtractor = null;
    }

    /**
     * 读取视轨文件
     *
     * @param pathway         轨道指针
     * @param mediaFormat     文件格式
     * @param save_video_path 文件保存路径
     */
    private void splitVideo(int pathway, MediaFormat mediaFormat, String save_video_path) {
        //  mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);//设置帧
        mediaExtractor.selectTrack(pathway);//选定轨道
        int videoMaxInputSize = mediaFormat.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);//获取缓冲最大字节
        MediaMuxer mediaMuxer = null;
        try {
            mediaMuxer = new MediaMuxer(save_video_path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        } catch (IOException e) {
            Log.e("error", "路径 save_video_path 错误" + e.getMessage());
        }

        int videoTrackIndex = mediaMuxer.addTrack(mediaFormat);//向合成器添加视频轨
        ByteBuffer inputBuffer = ByteBuffer.allocate(videoMaxInputSize);//分配缓冲
        mediaMuxer.start();

        MediaCodec.BufferInfo videoInfo = new MediaCodec.BufferInfo();//获取取出数据描述
        videoInfo.presentationTimeUs = 0;

        long videoSampleTime;
        //获取源视频相邻帧之间的时间间隔。(1)
        {
            mediaExtractor.readSampleData(inputBuffer, 0);
            //skip first I frame
            if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC)
                mediaExtractor.advance();
            mediaExtractor.readSampleData(inputBuffer, 0);
            long firstVideoPTS = mediaExtractor.getSampleTime();
            mediaExtractor.advance();
            mediaExtractor.readSampleData(inputBuffer, 0);
            long SecondVideoPTS = mediaExtractor.getSampleTime();
            videoSampleTime = Math.abs(SecondVideoPTS - firstVideoPTS);
        }
        mediaExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); //选择起点

        while (true) {
            int sampleSize = mediaExtractor.readSampleData(inputBuffer, 0);
            if (sampleSize < 0) {
                mediaExtractor.unselectTrack(pathway);   //这里一定要释放选择的轨道，不然另一个轨道就无法选中了
                break;
            }
            int sampleFlag = mediaExtractor.getSampleFlags();  //获取帧类型，只能识别是否为I帧(关键帧)
            mediaExtractor.advance();
            videoInfo.offset = 0;
            videoInfo.flags = sampleFlag;//帧类型
            videoInfo.size = sampleSize;//数据长度
            videoInfo.presentationTimeUs += videoSampleTime;//presentationTimeUs;
            mediaMuxer.writeSampleData(videoTrackIndex, inputBuffer, videoInfo);
        }
        mediaMuxer.stop();
        mediaMuxer.release();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast("视频分离完成");
            }
        });
    }


    /**
     * 音频读取
     *
     * @param audioTrack      轨道指针
     * @param format          文件格式
     * @param save_aideo_path 文件保存路径
     */
    private void splitAudio(int audioTrack, MediaFormat format, String save_aideo_path) {
        //  mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 10);//设置帧
        mediaExtractor.selectTrack(audioTrack);//选定轨道
        int videoMaxInputSize = format.getInteger(MediaFormat.KEY_MAX_INPUT_SIZE);//获取缓冲最大字节
        MediaMuxer mediaMuxer = null;
        try {
            mediaMuxer = new MediaMuxer(save_aideo_path, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4);
        } catch (IOException e) {
            Log.e("error", "路径 save_video_path 错误" + e.getMessage());
        }
        int videoTrackIndex = mediaMuxer.addTrack(format);//向合成器添加视频轨
        ByteBuffer inputBuffer = ByteBuffer.allocate(videoMaxInputSize);//分配缓冲
        mediaMuxer.start();

        MediaCodec.BufferInfo videoInfo = new MediaCodec.BufferInfo();//获取取出数据描述
        videoInfo.presentationTimeUs = 0;

        long videoSampleTime;
        //获取源视频相邻帧之间的时间间隔。(1)
        {
            mediaExtractor.readSampleData(inputBuffer, 0);
            //skip first I frame
            if (mediaExtractor.getSampleFlags() == MediaExtractor.SAMPLE_FLAG_SYNC)
                mediaExtractor.advance();
            mediaExtractor.readSampleData(inputBuffer, 0);
            long firstVideoPTS = mediaExtractor.getSampleTime();
            mediaExtractor.advance();
            mediaExtractor.readSampleData(inputBuffer, 0);
            long SecondVideoPTS = mediaExtractor.getSampleTime();
            videoSampleTime = Math.abs(SecondVideoPTS - firstVideoPTS);
        }
        mediaExtractor.seekTo(0, MediaExtractor.SEEK_TO_PREVIOUS_SYNC); //选择起点
        while (true) {
            int sampleSize = mediaExtractor.readSampleData(inputBuffer, 0);
            if (sampleSize < 0) {
                mediaExtractor.unselectTrack(audioTrack);   //这里一定要释放选择的轨道，不然另一个轨道就无法选中了
                break;
            }
            mediaExtractor.advance();
            videoInfo.size = sampleSize;
            videoInfo.flags = mediaExtractor.getSampleFlags();
            videoInfo.offset = 0;
            videoInfo.presentationTimeUs += videoSampleTime;
            Log.e("lll"," videoInfo.presentationTimeUs="+ videoInfo.presentationTimeUs+"    videoSampleTime="+videoSampleTime );
            mediaMuxer.writeSampleData(videoTrackIndex, inputBuffer, videoInfo);
        }
        mediaMuxer.stop();
        mediaMuxer.release();
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast("音频分类完成");
            }
        });

    }


}


